package sample.ui

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.PixelFormat
import android.os.Build
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import sample.ui.FloatControllerLayout.Companion.displayEvent
import sample.ui.FloatControllerLayout.Companion.showEvent
import com.netease.core.R
import com.tendcloud.tenddata.TalkingDataSDK
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.script.C
import kotlinx.coroutines.script.Controller
import kotlinx.coroutines.script.takeInitParam
import kotlinx.coroutines.script.tes.appScopeLaunch
import kotlinx.coroutines.script.tes.dp
import kotlinx.coroutines.script.tes.lifecycleOwner
import kotlinx.coroutines.script.tes.observe
import kotlinx.coroutines.script.tes.percentage
import kotlinx.coroutines.script.tes.phoneScreenHeight
import kotlinx.coroutines.script.tes.phoneScreenWidth
import kotlinx.coroutines.script.tes.printLog
import kotlinx.coroutines.script.tes.pt
import kotlinx.coroutines.withContext

import v9.assist.analyst.anaPathfindingModeFM
import v9.assist.analyst.anaPathfindingModeJT
import v9.assist.analyst.anaPathfindingModeRH
import v9.assist.analyst.anaPathfindingModeYW
import v9.assist.analyst.counterActionStopped
import v9.assist.initializeScreenshot
import v9.assist.script.sSceneCompletedTime
import v9.assist.script.xAtvLeftTime

class StatusLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs) {
    init {
        LayoutInflater.from(context).inflate(R.layout.slayout, this)
    }

    private val windowManager by lazy { context.getSystemService(Context.WINDOW_SERVICE) as WindowManager }
    private val windowParams: WindowManager.LayoutParams get() {
        return WindowManager.LayoutParams().also {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                it.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            } else {
                it.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
            }

            it.format = PixelFormat.RGBA_8888
            it.flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                    or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
            it.gravity = Gravity.START or Gravity.TOP
            it.x = leftOffset
            it.y = phoneScreenHeight - 15.dp // 200
//            it.y = 230.pt // 200
            it.width = findViewById<View>(R.id.container).layoutParams.width
            it.height = findViewById<View>(R.id.container).layoutParams.height
        }
    }
    private var statusJob: Job? = null
    private var animator: ValueAnimator? = null

    init {
        windowManager.addView(this, windowParams)
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        TalkingDataSDK.onPageBegin(context, "Controller")
        keepScreenOn = true
        val viewInfo = findViewById<TextView>(R.id.info)
        viewInfo.alpha = 0f

        Controller.running.observe(this) {
            if (!it) {
                alpha = 1f
                statusJob?.cancel()
            } else {
                viewInfo.text = ""
                statusJob?.cancel()
                statusJob = appScopeLaunch(Dispatchers.IO) {
                    printLog { "ControllerLayout restart running" }
                    while(true) {
                        delay(1000)
                        withContext(Dispatchers.Main) {
                            val e = appendInfo()
                            viewInfo.text = "| $sSceneCompletedTime ${xAtvLeftTime / 1000}s $counterActionStopped $e"
                        }
                    }
                }
            }
        }

        Controller.isInvalid.observe(this) {
            stopAnimation()
        }

        updateEvent.observe(this) {
            it?.also {
                windowManager.updateViewLayout(this, windowParams)
                viewInfo.alpha = 1f
            }
        }

        displayEvent.observe(this) {
            it?.also {
                visibility = if (it) VISIBLE else GONE
            }
        }

        Controller.clickStartStatus.observe(this) {
            if (!it && Controller.isRunning) {
                lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
                    delay(5000)
                    if (Controller.isRunning) this@StatusLayout.animate().alpha(0.3f).setDuration(400).start()
                    delay(20000)
                    if (Controller.isRunning) this@StatusLayout.animate().alpha(0.0f).setDuration(400).start()
                }
            }
        }
        showEvent.observe(this) {
            it?.also {
                animate().alpha(1f).start()
            }
        }

        lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
            initializeScreenshot(context)
        }
    }

    private fun appendInfo(): String {
        val e = when (Properties.scene) {
            C.S_FM -> anaPathfindingModeFM
            C.S_JT -> anaPathfindingModeJT
            C.S_YW -> anaPathfindingModeYW
            C.S_RH -> anaPathfindingModeRH
            else -> ""
        }
        return e.replace("p", "")
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        keepScreenOn = false
        stopAnimation()
    }

    companion object {
        private val leftOffset: Int get() {
            return takeInitParam("GOsMapLeft") ?: (phoneScreenWidth - 400.pt)
        }
        private var instance: StatusLayout? = null

        fun initialize(context: Context) {
            if (Permissions.isCaptureAbilityEnable
                && Permissions.isAccessibilityPermissionOpened) {
                release()
                StatusLayout(context).also { instance = it }
            }
        }

        fun release() {
            if (instance?.isAttachedToWindow == true) instance?.windowManager?.removeView(instance)
            instance = null
        }

        private val updateEvent = MutableLiveData<Any?>()
        fun notifyUpdate() {
            updateEvent.value = Any()
            updateEvent.value = null
        }
    }

    private fun stopAnimation() {
        animator?.cancel()
        alpha = 1f
    }
}